<template>
  <div class="tag-nav-wrapper">
    <div class="tags-nav">
      <div class="close-con">
        <Dropdown transfer @on-click="handleTagsOption" style="margin-top:7px;">
          <Button size="small" type="text">
            <Icon :size="18" type="ios-close-circle-outline" />
          </Button>
          <DropdownMenu slot="list">
            <DropdownItem name="close-all">关闭所有</DropdownItem>
            <DropdownItem name="close-others">关闭其他</DropdownItem>
          </DropdownMenu>
        </Dropdown>
      </div>
      <ul v-show="visible" :style="{left: contextMenuLeft + 'px', top: contextMenuTop + 'px'}" class="contextmenu">
        <li v-for="(item, key) of menuList" @click="handleTagsOption(key)" :key="key">{{ item }}</li>
      </ul>
      <div class="btn-con left-btn">
        <Button type="text" @click="handleScroll(240)">
          <Icon :size="18" type="ios-arrow-back" />
        </Button>
      </div>
      <div class="btn-con right-btn">
        <Button type="text" @click="handleScroll(-240)">
          <Icon :size="18" type="ios-arrow-forward" />
        </Button>
      </div>
      <div class="scroll-outer" ref="scrollOuter" @DOMMouseScroll="handlescroll" @mousewheel="handlescroll">
        <div ref="scrollBody" class="scroll-body" :style="{left: tagBodyLeft + 'px'}">
          <transition-group name="taglist-moving-animation">
            <Tag
              type="dot"
              v-for="(item, index) in list"
              ref="tagsPageOpened"
              :key="`tag-nav-${index}`"
              :name="item.name"
              :data-route-item="item"
              @on-close="handleClose(item.fullPath)"
              @click.native="handleClick(item)"
              :closable="item.fullPath !== homePage"
              @contextmenu.prevent.native="contextMenu(item, $event)"
            >{{ showTitleInside(item) }}</Tag>
          </transition-group>
          <!-- :color="isCurrentTag(item) ? 'primary' : 'default'"-->

        </div>
      </div>
    </div>
  </div>
</template>

<script>
import beforeClose from '@/router/before-close'
export default {
  name: 'TagsNav',
  data () {
    return {
      tagBodyLeft: 0,
      rightOffset: 40,
      outerPadding: 4,
      contextMenuLeft: 0,
      contextMenuTop: 0,
      visible: false,
      fullPathList: [],
      activeKey: '',
      list: [],
      menuList: {
        others: '关闭其他',
        all: '关闭所有'
      },
      homePage: '/home/index'
    }
  },
  computed: {
    currentRouteObj () {
      return this.value
    }
  },
  methods: {
    handlescroll (e) {
      var type = e.type
      let delta = 0
      if (type === 'DOMMouseScroll' || type === 'mousewheel') {
        delta = (e.wheelDelta) ? e.wheelDelta : -(e.detail || 0) * 40
      }
      this.handleScroll(delta)
    },
    handleScroll (offset) {
      const outerWidth = this.$refs.scrollOuter.offsetWidth
      const bodyWidth = this.$refs.scrollBody.offsetWidth
      if (offset > 0) {
        this.tagBodyLeft = Math.min(0, this.tagBodyLeft + offset)
      } else {
        if (outerWidth < bodyWidth) {
          if (this.tagBodyLeft < -(bodyWidth - outerWidth)) {
            this.tagBodyLeft = this.tagBodyLeft
          } else {
            this.tagBodyLeft = Math.max(this.tagBodyLeft + offset, outerWidth - bodyWidth)
          }
        } else {
          this.tagBodyLeft = 0
        }
      }
    },
    handleTagsOption (type) {
      if (type.includes('all')) {
        // 关闭所有，除了home
        const res = this.list.filter(item => item.name === homePage)
        this.$emit('on-close', res, 'all')
      } else if (type.includes('others')) {
        // 关闭除当前页和home页的其他页
        const res = this.list.filter(item => routeEqual(this.currentRouteObj, item) || item.name === homePage)
        this.$emit('on-close', res, 'others', this.currentRouteObj)
        setTimeout(() => {
          this.getTagElementByName(this.currentRouteObj.name)
        }, 100)
      }
    },
    handleClose (current) {
      if (current.meta && current.meta.beforeCloseName && current.meta.beforeCloseName in beforeClose) {
        new Promise(beforeClose[current.meta.beforeCloseName]).then(close => {
          if (close) {
            this.close(current)
          }
        })
      } else {
        this.close(current)
      }
    },
    close (targetKey) {
      this.list = this.list.filter(page => page.fullPath !== targetKey)
      this.fullPathList = this.fullPathList.filter(path => path !== targetKey)
      // 判断当前标签是否关闭，若关闭则跳转到最后一个还存在的标签页
      if (!this.fullPathList.includes(this.activeKey)) {
        // this.selectedLastPath()
      }
    },
    handleClick (item) {
      this.$emit('input', item)
    },
    showTitleInside (item) {
      return item.meta.title || item.name
    },
    isCurrentTag (item) {
      return routeEqual(this.currentRouteObj, item)
    },
    moveToView (tag) {
      const outerWidth = this.$refs.scrollOuter.offsetWidth
      const bodyWidth = this.$refs.scrollBody.offsetWidth
      if (bodyWidth < outerWidth) {
        this.tagBodyLeft = 0
      } else if (tag.offsetLeft < -this.tagBodyLeft) {
        // 标签在可视区域左侧
        this.tagBodyLeft = -tag.offsetLeft + this.outerPadding
      } else if (tag.offsetLeft > -this.tagBodyLeft && tag.offsetLeft + tag.offsetWidth < -this.tagBodyLeft + outerWidth) {
        // 标签在可视区域
        this.tagBodyLeft = Math.min(0, outerWidth - tag.offsetWidth - tag.offsetLeft - this.outerPadding)
      } else {
        // 标签在可视区域右侧
        this.tagBodyLeft = -(tag.offsetLeft - (outerWidth - this.outerPadding - tag.offsetWidth))
      }
    },
    getTagElementByName (route) {
      this.$nextTick(() => {
        this.refsTag = this.$refs.tagsPageOpened
        this.refsTag.forEach((item, index) => {
          if (routeEqual(route, item.$attrs['data-route-item'])) {
            const tag = this.refsTag[index].$el
            this.moveToView(tag)
          }
        })
      })
    },
    contextMenu (item, e) {
      if (item.name === this.homePage) {
        return
      }
      this.visible = true
      const offsetLeft = this.$el.getBoundingClientRect().left
      this.contextMenuLeft = e.clientX - offsetLeft + 10
      this.contextMenuTop = e.clientY - 64
    },
    closeMenu () {
      this.visible = false
    },
    addTag (newVal) {
      this.activeKey = newVal.fullPath
      if (this.fullPathList.indexOf(newVal.fullPath) < 0) {
        this.fullPathList.push(newVal.fullPath)
        this.list.push(newVal)
      }
    }
  },
  watch: {
    '$route' (newVal) {
      console.log(newVal)
      this.addTag(newVal)
    },
    visible (value) {
      if (value) {
        document.body.addEventListener('click', this.closeMenu)
      } else {
        document.body.removeEventListener('click', this.closeMenu)
      }
    }
  },
  created () {
    this.list.push(this.$route)
    this.fullPathList.push(this.$route.fullPath)
  }
}
</script>

<style lang="less">
@import './tags-nav.less';
</style>
